#include "global.h"
//--------------------------------------------------------------------------------------------------------------------------
//
//==========================================================================================================================
//		Important parameters
//		TMR1 tick  	every 	5ms
//		Pulse_tick  every	40ms
//		System_tick every 	250ms
//==========================================================================================================================
//
//--------------------------------------------------------------------------------------------------------------------------

//--------------------------------------------------------------------------------------------------------------------------
//      V  A  R  I  A  B  L  E  S  
//--------------------------------------------------------------------------------------------------------------------------


bit Packet_ready;
bit TxRx_Error;
bit tout_enable;
bit rx_buf_full;
bit tx_busy;
bit handshaiking;
bit flag_error_norx;
bit flag_itu_start;

//bit PacketReceived;

bit flag_time_on;



bank1 unsigned char rx_buf[RX_BUF_LENGHT];
bank1 unsigned char rx_buf_index=0;
bank1 unsigned char rx_buf_start=10;
bank1 unsigned char rx_packet_lenght=31;
bank1 unsigned char rx_byte_tout;
bank1 unsigned char txrxpause;

// static bank3 signed char itu_packet_counter=3;


static bank3  unsigned int secs;  
static bank3  unsigned int seccount =0;
static bank3  unsigned int gsecs;  
static bank3  unsigned int gseccount =0;
bank3 struct sTime myTime;
//unsigned char stop_me=0;

bank2 unsigned char tx_buf[TX_BUF_LENGHT];
bank2 unsigned char tx_count=0;
bank2 unsigned char tx_buf_index=0;

bank1 unsigned char SystemTickCount=20; 
bank1 unsigned char PulseTickCount=5; 
bank1 unsigned int	RXWatchdog=2000; // 10sek/5ms = 10000/5=2000; 
bank1 unsigned char CommunicationState;



//--------------------------------------------------------------------------------------------------------------------------
//      F  U  N  C  T  I  O  N  S
//--------------------------------------------------------------------------------------------------------------------------





//--------------------------------------------------------------------------------------------------------------------------
unsigned char Get_Buf_Byte (unsigned char buff_start, unsigned char buff_position)
{	unsigned char temp;
	if ((buff_start + buff_position) < RX_BUF_LENGHT) 
	{	
		temp=buff_start+buff_position;
	}
	else
	{ 
		temp = (buff_start + buff_position ) -RX_BUF_LENGHT;
	};
	return rx_buf[temp];
};




void resetTime()
{
	seccount =0;
	secs=0;
};

unsigned int getSec(void)
{  
	return secs;
};


void resetgTime()
{
	gseccount =0;
	gsecs=0;
};

unsigned int getgSec(void)
{  
	return gsecs;
};


void EnableTime(void)
{
	flag_time_on=1;
};

void DisableTime(void)
{
	flag_time_on=0;
};

void interrupt												// Here be interrupt function - the name is
isr(void)															// unimportant.
{ 	unsigned char temp_a,temp_i,temp_i1;
	static bank1 unsigned char checksum_reg;
	static unsigned char temp_dc, sum_dc;
	static bank3 signed char itu_packet_counter=2;
//--------------------------------------------------------


	if (TMR1IE && TMR1IF)
	{ 	TMR1IF=0;
		TMR1Preload (65535-Tick+CAL_FACTOR);				// tick 5 ms
		if (!SystemTickCount--)
		{	SystemTickCount=50; 			// 250ms
			flag_system_tick=1;
		};

// ------- here we must care a receiver ----------------
		

// ================== Time Indication Section ========================
		if(flag_time_on) // seems need only in sequence running situation
		{		if (seccount++ >200)
				{	secs+=1;
					seccount=0;
				};

				if (gseccount++ >200)
				{	gsecs+=1;
					if((myTime.seconds +=1) >59)
					{	myTime.seconds=0;
						if ((myTime.minutes+=1)>59)
						{	myTime.minutes=0;
							if ((myTime.hours+=1)>24) myTime.hours=0;
						}
					}
					gseccount=0;
				};
		};  
// ================== Pulse Tick 40ms  ========================


		ServiceLamps();

		if (!PulseTickCount--)
		{	PulseTickCount=8;  //  40 ms 
			flag_pulse_tick=1;
			ServiceInputs();
		};
//=============================================================

		if (flag_com_pause)
		{
			if (!txrxpause--) flag_com_pause=0;
		};


//================================================================================================================
//================== C O M M U N I C A T I O N     S T A T E M A S H I N E =======================================
//================================================================================================================
				
		 // here we waiting for packet and if it good we start the job
		switch(CommunicationState)
		{

				case 0:
					if (flag_packet_received)
					{	flag_packet_received=0;
						CREN=0;
						if ((Odu==sourse)&&(Idu==destination))	// single part
						{	
						#ifndef NOIDU
							CommunicationState =6; // send IDU mess
						#else
							if (flag_itu_start)	
							{
								CommunicationState =2;  // send ITU command
							}
							else
							{
								CommunicationState =1;	// continue listening
							}
						#endif
						} // main here is fast return to listening line
				 		else if ((Odu==sourse)&&(kCOM==destination))
						{	
							if ( itu_packet_counter-- < 0)
							{
								itu_packet_counter=2;
								CommunicationState = 0;	// goto wait for packet
								CREN=1;					// we return to receiving state so need to enable receiver 
							}
							else
							{
								CommunicationState = 2; 									
							}	
						} // main here is a time between receive and send
						else if ((Idu==sourse)&&(Odu==destination))	// full system
						{	CommunicationState =0;
						}
						else if ((Odu==sourse)&&(MSMP==destination))	// full system
						{	CommunicationState =0;
							asm("nop");
						}
						else 
						{
							CREN=1;
							CommunicationState =0;
						};
					}; // END OF PACKET RECEIVED
					break;



				case 1:		CommunicationState = 0; 	// goto wait for packet
							CREN=1;					// we return to receiving state so need to enable receiver 
					break;

				case 2:										
							flag_com_pause=1;
							txrxpause=70; // 70*5ms = 350ms pause between RX and TX
							CommunicationState =3; 	
							asm("nop");	
					break;


				case 3:		if(!flag_com_pause)
							{	tx_count=12;
								sum_dc=0;
								if (ITUMsgId++ >31) ITUMsgId=0; 

								for (temp_dc=0; temp_dc<4; temp_dc++)
								{	tx_buf[temp_dc]=ITUHeader[temp_dc];
								};
								tx_buf[4]=ITUMsgId;

								//---------- next block must be changed due to work with real  ITU---------
								for (temp_dc=0; temp_dc<6;temp_dc++)
								{	tx_buf[temp_dc+5]=MyITU.access[temp_dc];
								};

								for (temp_dc=0; temp_dc<11;temp_dc++)
								{	sum_dc+=tx_buf[temp_dc];
								};

								tx_buf[11]=(unsigned char)(0-sum_dc);					

								tx_buf_index=0;
								TXIE=1;
								CommunicationState =4;  
							}	
					break;

				case 4:		if(!TXIE)
							{	
								flag_com_pause=1;
								txrxpause=12; // 12*5ms = 60ms pause between RX and TX
								CommunicationState =5; 	
								asm("nop");	
							}
					break;

				case 5:		if (!flag_com_pause)
							{	// Lets wait up to delay end and start receiver here
								CREN=1;
								CommunicationState =0; 
							};
					break;


				case 6:		flag_com_pause=1;
							txrxpause=12; // 12*5ms = 60ms pause between RX and TX
							CommunicationState =7; 	
							asm("nop");
					break;

				case 7:		if(!flag_com_pause)
							{	tx_count=26;
								sum_dc=0;
								if (IDUMsgId++ >31) IDUMsgId=0; 

								for (temp_dc=0; temp_dc<4; temp_dc++)
								{	tx_buf[temp_dc]=IDUHeader[temp_dc];
								};
								tx_buf[4]=IDUMsgId;

								//---------- next block must be changed due to work with real  IDU---------
								for (temp_dc=0; temp_dc<20;temp_dc++)
								{	tx_buf[temp_dc+5]=MyIDU.access[temp_dc];
								};

								for (temp_dc=0; temp_dc<25;temp_dc++)
								{	sum_dc+=tx_buf[temp_dc];
								};

								tx_buf[25]=(unsigned char)(0-sum_dc);					

								tx_buf_index=0;
								TXIE=1;
								CommunicationState =8;    // beware 4!!!!!!
							};	
					break;

				case 8:		if(!TXIE)
							{	
								flag_com_pause=1;
								txrxpause=12; // 12*5ms = 60ms pause between RX and TX
								if (flag_itu_start)
								{ 	
									CommunicationState =3;  // send itu packet	
									asm("nop");
								}
								else
								{
									CommunicationState =9; 	// continue odu-idu emulation
									asm("nop");				
								};	
							};
					break;

				case 9:		if (!flag_com_pause)
							{	// Lets wait up to delay end and start receiver here
								CREN=1;
								CommunicationState =0; 
							};
					break;

				default:
							CREN=1;
							TXIE=0;
							RCIE=1;
							CommunicationState =0; 	
					break;
				}; // end of switch 

//==========================================================================================================================
	}; // end of T1 interrupt
//------------------------------------------------------------------------------------------
while(RCIF && RCIE)// (RCIF) to prevent FIFO overflow
{	
	if (OERR || FERR)
	{ 	CREN=0;
		temp_i=RCREG;
		CREN=1;
	}
	else
	{
		temp_i1=RCREG;


		// prepare to add a new byte to the circular buffer
		//			Put_Buf_Byte(temp_i1);
		if ((rx_buf_index+1)< RX_BUF_LENGHT ) // check if buffer not full 
			{	rx_buf_index+=1;						// increment byte index
			}
			else					// if buffer full
			{	rx_buf_full =1;	// report it
				rx_buf_start+=1;	// move  start point forward (first recorded byte will be lost)
				if (rx_buf_start >= RX_BUF_LENGHT) rx_buf_start=0;
			};  	//end of  place check and preparation 
	
				// here we  store recorded byte
		if ((rx_buf_index+rx_buf_start) < RX_BUF_LENGHT)
			{ 	rx_buf[rx_buf_start+rx_buf_index]=temp_i1;	
			}
			else
			{ 	
				rx_buf[(rx_buf_start + rx_buf_index)-RX_BUF_LENGHT]=temp_i1;	
			};
			// here we performing  packet job
			//  if start marker received -  move buffer start to marker position, reset index and prepare check sum


			checksum_reg+=temp_i1; 		//  calculating chaecksum	
		
			//====================== New Sync Byte received ==============================
			if (0xFE==temp_i1)
			{  	if ((rx_buf_start+rx_buf_index)>RX_BUF_LENGHT)
				{	rx_buf_start=(rx_buf_start+rx_buf_index)-RX_BUF_LENGHT;
				}
				else
				{	rx_buf_start=rx_buf_start+rx_buf_index;
				};
				rx_buf_index=0;
				checksum_reg=0xFE;
			};	// end of sync seeking
			
			//============================================================================

			if (3 == rx_buf_index )
			{
				 rx_packet_lenght = temp_i1 & 0b00011111; //  max =31 byte
			};

			if ( (rx_packet_lenght -1) == rx_buf_index )
			{	
				asm("nop");	
				if ( 0 == checksum_reg )
				{	
				// heer we check sourse and destination of received packet
					sourse = (Get_Buf_Byte (rx_buf_start,2)&0b00000111) ; // sourse
					destination = (Get_Buf_Byte (rx_buf_start,1)&0b00000111) ; // destination
				// here we copying the data packets 
				
					if (( sourse == Odu)&&( destination == Idu ))  //	Odu->Idu
					{	for (temp_i=0; temp_i<5;temp_i++)
						{	MyODUIDUHeader.access[temp_i]=Get_Buf_Byte (rx_buf_start,temp_i);
						};
						for (temp_i=0; temp_i<rx_packet_lenght-2;temp_i++)
						{	MyODU.access[temp_i]=Get_Buf_Byte (rx_buf_start,temp_i+5);
						};
					};
					//------------------------------------
					if (( sourse == Idu)&&( destination == Odu ))  //	Odu->Idu
					{	for (temp_i=0; temp_i<5;temp_i++)
						{	MyIDUHeader.access[temp_i]=Get_Buf_Byte (rx_buf_start,temp_i);
						};
						for (temp_i=0; temp_i<rx_packet_lenght-2;temp_i++)
						{	MyIDU.access[temp_i]=Get_Buf_Byte (rx_buf_start,temp_i+5);
						};
					};
				//------------------------------------
					if (( sourse == Odu)&&( destination == kCOM ))  //	Odu->kCOM
					{	for (temp_i=0; temp_i<5;temp_i++)
						{	MyODUkCOMHeader.access[temp_i]=Get_Buf_Byte (rx_buf_start,temp_i);
						};
						for (temp_i=0; temp_i<rx_packet_lenght-2;temp_i++)
						{	MyITU_answer.access[temp_i]=Get_Buf_Byte (rx_buf_start,temp_i+5);
						};
						asm("nop");
					};
				//------------------------------------
					if (( sourse == kCOM)&&( destination == Odu ))  // kCOM->ODU  this is our packet - do nothing
					{
				
					};
//====================================================
					flag_packet_good=1;
					flag_packet_received=1;
					flag_packet_tov.Set=0xff;
				};
			};
	}; // end of no OERR/FERR
};	// end of while RCIF

//--------------------------------------------------------
	if (T0IF && T0IE)
	{	UpdateTMR0();			// reset interrupt flag
		SetTickLCD();
		ADGO=1;					// start adc convertion with preselected ADC0 input  - Curent input
	}; // end of T0 interrupt
//----------------------------------------------------------

	if (ADIE && ADIF)
	{
		ADIF=0;
		if(!CHS0)
		{	ADC2Buffer();
			CHS0=1;
			temp_a=12;
			while(temp_a--) continue; // 24uS  acquisition time delay 
			ADGO=1;
		}
		else
		{
			ADC2Temp();
			CHS0=0;
			temp_a=12;
			while(temp_a--) continue; // 24uS  acquisition time delay 
		}
	}


//------------------------- transmitting section ----------
	while (TXIF && TXIE)
	{
		if(tx_count) 
		{	tx_count--;
			TXREG = tx_buf[tx_buf_index++];
		} else 
		{	TXIE=0;
		}; // 		
	}; // end of  TXIF

	//==============================
	if (CMIF&&CMIE)
	{ 
		CMIF=0;
		CMIE=0;	
	 };

	if (EEIF&&EEIE)
	{	EEIF=0;
		EEIE=0;
	};

	if (PSPIF&&PSPIE)
	{	PSPIF=0;
		PSPIE=0;
	};

	if( SSPIF&&SSPIE)
	{	SSPIF=0;
		SSPIE=0;
	};

	if (CCP1IF&&CCP1IE)
	{	CCP1IF=0;
		CCP1IE=0;
	};

	if (CCP2IF&&CCP2IE)
	{	CCP2IF=0;
		CCP2IE=0;
	};

	if (BCLIF&&BCLIE)
	{	BCLIF=0;
		BCLIE=0;
	};




}; // end of interrupt


